package com.hxh.wechat.activity

import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.children
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.gson.JsonObject
import com.hxh.wechat.R
import com.hxh.wechat.adpter.ChatMessageAdapter
import com.hxh.wechat.adpter.ContactAdapter
import com.hxh.wechat.adpter.EmojiAdapter
import com.hxh.wechat.api.FileApi.Companion.uploadFile
import com.hxh.wechat.constant.GlobalConstant
import com.hxh.wechat.model.*
import com.hxh.wechat.util.ClientSocket
import com.hxh.wechat.util.DBUtil
import com.hxh.wechat.util.EmoJiUtils
import com.hxh.wechat.voide.CallVideoActivity
import com.hxh.wechat.voide.RandomString
import com.nostra13.universalimageloader.core.ImageLoader
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import uk.co.senab.photoview.PhotoView
import uk.co.senab.photoview.PhotoViewAttacher
import java.util.*
import java.util.concurrent.ExecutionException


class ChatPageActivity: BaseActivity(), View.OnClickListener {
    class ChatMessage(
        val targetImage: String,//联系人的图片
        val contactName: String,//联系人的名字
        val time: Date,//日期
        val content: String,//消息的内容
        val isMe: Boolean,
        val type: Int
    )//这个消息是不是我发出的?

    private val PICK_FILE_REQUEST = 1

    private lateinit var editMessage: EditText
    private lateinit var emojiButton: ImageView
    private lateinit var emojiRecyclerView: RecyclerView
    private lateinit var user: UserInfo
    private var isEmojiShown = false

    companion object {
        val chatMessageList = ArrayList<ChatMessage>()
        var contact: ContactAdapter.ContactItem =
            ContactAdapter.ContactItem("xxx", "xxx", "xxx", "xxx")
        lateinit var recyclerView: RecyclerView

        fun goChat(context: Context, contact: ContactAdapter.ContactItem) {
            var intent = Intent(context, ChatPageActivity::class.java)
            val bundle = Bundle().apply {
                putString("contactUserId", contact.friendUserId)
                putString("contactImg", contact.contactImg)
                putString("contactName", contact.contactName)
                putString("contactNickname", contact.friendNickname)
                // 将 contact 其他需要传递的属性也添加到 Bundle 中
            }
            intent.putExtras(bundle);
            context.startActivity(intent)
        }

        fun initRecyclerView(recyclerView: RecyclerView) {
            this.recyclerView = recyclerView
            this.recyclerView.adapter = ChatMessageAdapter(chatMessageList)
        }

        fun notifyDataSetChanged() {
            Handler(Looper.getMainLooper()).post {
                recyclerView.adapter?.notifyDataSetChanged()
            }
        }

        //初始化快照数据
        private fun loadChatHistoryData() {
            chatMessageList.clear()
            var historyData: ArrayList<ChatHistory> =
                getUserChatHistoryData(context = recyclerView.context, contact.friendUserId)!!
            var user = DBUtil.getUser(con = recyclerView.context)
            for (history in historyData) {
                history.isRead = true
                if (history.isMe) {
                    chatMessageList.add(
                        ChatMessage(
                            user!!.faceImage,
                            user.nickname,
                            history.Date,
                            history.msg,
                            history.isMe,
                            history.type
                        )
                    )
                } else {
                    chatMessageList.add(
                        ChatMessage(
                            contact.contactImg,
                            contact.friendNickname,
                            history.Date,
                            history.msg,
                            history.isMe,
                            history.type
                        )
                    )
                }
            }
            //全覆盖
            coverUserChatHistory(
                chatHistoryList = historyData,
                context = recyclerView.context,
                friendId = contact.friendUserId
            )
        }
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 消息视图控制器
        setContentView(R.layout.chat_page)
        val recyclerView = findViewById<RecyclerView>(R.id.chatMessageListView)
        initRecyclerView(recyclerView)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = ChatMessageAdapter(chatMessageList)
        //获取intent接受的数据
        val bundle = intent.extras
        if (bundle != null) {
            // 从 Bundle 中提取 contact 对象
            contact = ContactAdapter.ContactItem(
                bundle.getString("contactUserId", ""),
                bundle.getString("contactImg", ""),
                bundle.getString("contactName", ""),
                bundle.getString("contactNickname", ""),
                // 提取其他需要的属性
            )
        }
        user = DBUtil.getUser(con = this)!!

        findViewById<TextView>(R.id.chatTtile).text = contact.friendNickname
        var chatBack = findViewById<ImageView>(R.id.chatBack)
        loadChatHistoryData()

        //表情包模块
        // 获取界面组件
        emojiButton = findViewById(R.id.send_emo)
        emojiRecyclerView = findViewById(R.id.emoji_recycler_view)
        editMessage = findViewById(R.id.editMessage)
        // 创建 EmojiAdapter 对象
        val emojiAdapter = EmojiAdapter(EmoJiUtils.allRes) { emoji ->
            insertEmoji(emoji)

        }

        // 设置表情选择器
        emojiRecyclerView.layoutManager = GridLayoutManager(this, 12)
        emojiRecyclerView.adapter = emojiAdapter
        // 设置表情按钮的点击事件
        emojiButton.setOnClickListener {
            if (isEmojiShown) {
                hideEmoji()
            } else {
                showEmoji()
            }
        }
        // 获取 add_menu ImageView
        val addMenu: ImageView = findViewById(R.id.add_menu)
        // 添加 OnClickListener
        addMenu.setOnClickListener { // 创建 BottomSheetDialog
            //关闭表情包页面
            hideEmoji()
            val bottomSheetDialog = BottomSheetDialog(this@ChatPageActivity)
            // 将 bottom_sheet_menu.xml 布局文件添加到 BottomSheetDialog 中
            val view =
                LayoutInflater.from(this@ChatPageActivity).inflate(R.layout.bottom_sheet_menu, null)
            bottomSheetDialog.setContentView(view)
            // 显示 BottomSheetDialog
            bottomSheetDialog.show()
            bottomSheetDialog.findViewById<LinearLayout>(R.id.fileUpload)!!.setOnClickListener {
                // 启动文件选择器
                val intent = Intent(Intent.ACTION_GET_CONTENT)
                intent.type = "*/*"
                startActivityForResult(intent, PICK_FILE_REQUEST)
            }

            //启动音视频通话聊天
            bottomSheetDialog.findViewById<LinearLayout>(R.id.chatVideo)!!.setOnClickListener {
                //在启动聊天应该生成房间号 然后推送给对方 如果对方离线就提示对方下线
                var roomId =
                    "roomdId:" + user.id + "#" + contact.friendUserId + RandomString.length(5);
                //封装socket消息体
                var content = DataContent(
                    MsgActionEnum.CHAT.type,
                    Msg(user.id, contact.friendUserId, 0, roomId, ""),
                    "video"
                )
                ClientSocket.chat(content)
            }
        }
        //发送消息
        findViewById<Button>(R.id.buttonSend).setOnClickListener(this)

        chatBack.setOnClickListener {
            ActivityChat.initStar()
            //页面退出时清空contact
            contact = ContactAdapter.ContactItem("xxx", "xxx", "xxx", "xxx")
            finish()

        }
        recyclerView.scrollToPosition(chatMessageList.size - 1)
    }

    //发送消息
    fun sendMsg(msg: String, context: Context, type: Int) {
        var chatMessage =
            ChatMessage(
                user!!.faceImage,
                user.username,
                Date(),
                msg,
                true,
                type
            )
        //封装socket消息体
        var content = DataContent(
            MsgActionEnum.CHAT.type,
            Msg(user.id, contact.friendUserId, type, msg, ""),
            ""
        )
        ClientSocket.chat(content)
        chatMessageList.add(chatMessage)
        //清空ditMessage数据
        editMessage.text.clear();

        //监听聊天下滑
        notifyDataSetChanged()
        val position = chatMessageList.size - 1
        GlobalScope.launch(Dispatchers.Main) {
            recyclerView.scrollToPosition(position)
        }

        //保存聊天记录
        saveUserChatHistory(
            chatHistory = ChatHistory(
                "",
                user.id, contact.friendUserId,
                msg, true, type, true, Date()
            ), context = context
        )
        //保存快照
        saveUserChatSnapshot(
            chatSnapshot = ChatSnapshot(
                user.id,
                contact.friendUserId,
                contact.contactImg,
                contact.friendNickname,
                Date(),
                msg,
                true,
                type
            ), context = context
        );
    }

    override fun onClick(o: View?) {
        //关闭表情包页面
        hideEmoji()
        val context = o?.context!!
        //现在还不能真正发出消息，把消息放在chatMessages中，显示出来即可
        val msg = editMessage.text.toString();
        if (msg == "") {
            DBUtil.popMsg(
                "内容不能为空",
                context
            );
            return;
        }

        sendMsg(msg, context, MsgType.TEXT.type)

    }

    // 显示表情选择器
    private fun showEmoji() {
        isEmojiShown = true
        emojiRecyclerView.visibility = View.VISIBLE
    }

    // 隐藏表情选择器
    private fun hideEmoji() {
        isEmojiShown = false
        emojiRecyclerView.visibility = View.GONE
    }

    // 插入表情符号
    private fun insertEmoji(emoji: String) {
        println(emoji)
        /* val start = editMessage.selectionStart
         val end = editMessage.selectionEnd
         editMessage.text.replace(Math.min(start, end), Math.max(start, end), emoji, 0, emoji.length)*/
        val selectionStart: Int = editMessage.getSelectionStart()
        val body: String = editMessage.getText().toString()
        val stringBuilder = StringBuilder(body)
        stringBuilder.insert(selectionStart, emoji)
        editMessage.setText(EmoJiUtils.parseEmoJi(1, this, stringBuilder.toString()))
        editMessage.setSelection(selectionStart + emoji.length)
    }

    // 获取文件路径并上传文件
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PICK_FILE_REQUEST && resultCode == RESULT_OK && data != null && data.data != null) {
            GlobalScope.launch(Dispatchers.IO) {
                val uri = data.data!!
                val filePath = getRealPathFromURI(uri)!! // 替换为自己实现的方法，将uri转化为文件路径
                try {
                    val responseCode = uploadFile(filePath) // 调用上传文件的方法
                    //回调图片url 进行图片信息的发送
                    sendMsg(
                        GlobalConstant.IMAGES_URL + DBUtil.getGson()
                            .fromJson(responseCode, JsonObject::class.java)
                            .get("data").asString,
                        recyclerView.context,
                        MsgType.IMAGE.type
                    )
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

    fun getRealPathFromURI(uri: Uri): String? {
        var filePath: String? = null
        try {
            val file = Glide.with(this)
                .asFile()
                .load(uri)
                .submit()
                .get()

            filePath = file.absolutePath
        } catch (e: ExecutionException) {
            e.printStackTrace()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }

        return filePath
    }
}